﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using GalaSoft.MvvmLight.Messaging;
using NetBay.Core.BusinessEntities;
using NetBay.Core.BusinessEntities.Workflow;
using NetBay.Core.Encryption.Licensing;
using Rio.Application.RioWeb.Flow.Controls;
using Rio.Applications.Web.Services;
using Rio.Flow.Application.Models.Flow;
using Rio.Framework.Localisation;
using Rio.Framework.Pages;
using Rio.Framework.Pages.AppCode.Enums;
using Rio.Framework.Pages.AppCode.Helpers;
using Rio.Framework.Pages.AppCode.Models;
using Rio.Framework.Pages.Context;
using Rio.Framework.Pages.Controls;
using Rio.Framework.Pages.Enums;
using Rio.Framework.Pages.Helpers;
using Rio.Framework.Pages.Workflow;
using Rio.Framework.Pages.Workflow.BaseClass;
using Telerik.Windows;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.GridView;
using Rio.Framework.Pages.Manager;
using System.Text;
using Rio.Framework.Pages.Workflow.Models;

namespace Rio.Application.RioWeb.Flow.Views
{
    #region Enumerations

    public enum FlowDisplayMode
    {
        Classic,
        Workflow
    }

    #endregion Enumerations

    /// <summary>
    /// This class displays received and sent messages.
    /// </summary>
    public partial class FlowView : INotifyPropertyChanged
    {
        #region Fields

        public static readonly DependencyProperty DataContextViewModelProperty =
            DependencyProperty.Register("DataContextViewModel", typeof(DataViewModel), typeof(FlowView), null);

        public static readonly DependencyProperty FlowStructureItemsProperty =
            DependencyProperty.Register("FlowStructureItems", typeof(ObservableCollection<FlowTreeModel>), typeof(FlowView), null);

        public static readonly DependencyProperty SelectedDataItemTreeViewProperty =
            DependencyProperty.Register("SelectedDataItemTreeView", typeof(Framework.Pages.Workflow.Models.DataItemTreeView), typeof(FlowView), new System.Windows.PropertyMetadata(
                null,
                (s, e) =>
                {
                    if (e.NewValue != null)
                    {
                        ((FlowView)s).ChangeDisplayMode(FlowDisplayMode.Workflow);
                        ((FlowView)s).WorkflowInstanceList.RefreshWorkflowInstances(e.NewValue as Framework.Pages.Workflow.Models.DataItemTreeView);
                    }
                }));
        public static readonly DependencyProperty AdminDataViewModelProperty =
            DependencyProperty.Register("AdminDataViewModel", typeof(AdminDataViewModel), typeof(FlowView), null);

        private GridViewFilterDescriptor customFilterDescriptor;
        private bool m_bDataHasChanged;
        private string m_FolderLbl = string.Empty;
        private string m_NbMaxTabMessage = string.Empty;
        private List<MessageFlowDisp> m_oSelectedListMsg;
        private Dictionary<RadTabItem, long> m_oTabItemsFlow = new Dictionary<RadTabItem, long>();
        private Dictionary<RadTabItem, long> m_oTabItemsWorkflow = new Dictionary<RadTabItem, long>();
        private string m_sDeleteMessage = "";
        private string m_sDeleteMessageHeader = "";
        private LoadingIndicatorManager _busyIndicator = new LoadingIndicatorManager();
        private FlowDisplayMode _flowDisplayMode;
        private ObservableCollection<ObservableKeyValuePair<WorkflowInstance, Folder>> _workflowInstancewMessagesWithIndex =
            new ObservableCollection<ObservableKeyValuePair<WorkflowInstance, Folder>>();
        private int _tabCount = 1;
        private int _lastSelectedTabIndex;

        private bool _isLoading;

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Constructor
        /// </summary>
        public FlowView()
        {
            InitializeComponent();
            busyIndicator.BusyContent = Resx.GetLabel(ResxCommon.LOADING_PAGE);

            // Initialize the DoubleClickTimer
            DoubleClickTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 0, 300) };
            DoubleClickTimer.Tick += DoubleClick_Timer;

            EventManager.RegisterClassHandler(typeof(RadTabItem), RoutedEventHelper.CloseTabEvent, new RoutedEventHandler(OnCloseTabClicked));

            InitLabel();

            //Add double click event on the gridview
            (GridViewMessages as RadGridView).AddHandler(GridViewCell.MouseLeftButtonUpEvent, new MouseButtonEventHandler(Item_MouseLeftButtonUp), true);

            FlowDisplayMode = FlowDisplayMode.Classic;

            if (LoginManager.Instance.CurrentUser != null)
                Initialization();
            else
            {
                //if (LoginManager.Instance.AuthenticationMethod == LoginDomainServiceEnums.AuthenticationMethod.SSO)
                //{
                    LoginManager.Instance.AuthenticatedUser += (sender, args) => Initialization();
                //}
            }
        }

        public void Initialization()
        {
            headMenu.LoadUser(ApplicationName.RioFlow);
            
            //Init data Context
            InitDataContext();

            //For admin tab
            OrganizationTypeControl.InitControl(AppDisplayMode.Admin);

            InitializeWokflowMode();

            busyIndicator.Visibility = Visibility.Collapsed;
        }

        #endregion Constructors

        #region Events

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion Events

        #region Properties

        /// <summary>
        /// Gets or sets the index of the workflow instancew messages with.
        /// </summary>
        /// <value>The index of the workflow instancew messages with.</value>
        public ObservableCollection<ObservableKeyValuePair<WorkflowInstance, Folder>> WorkflowInstancewMessagesWithIndex
        {
            get { return _workflowInstancewMessagesWithIndex; }
            set
            {
                _workflowInstancewMessagesWithIndex = value;
                OnPropertyChanged("WorkflowInstancewMessagesWithIndex");
            }
        }

        /// <summary>
        /// Gets or sets the data context view model.
        /// </summary>
        /// <value>The data context view model.</value>
        public DataViewModel DataContextViewModel
        {
            get { return (DataViewModel)GetValue(DataContextViewModelProperty); }
            set { SetValue(DataContextViewModelProperty, value); }
        }

        /// <summary>
        /// Gets or sets the admin data view model.
        /// </summary>
        /// <value>The admin data view model.</value>
        public AdminDataViewModel AdminDataViewModel
        {
            get { return (AdminDataViewModel)GetValue(AdminDataViewModelProperty); }
            set { SetValue(AdminDataViewModelProperty, value); }
        }

        /// <summary>
        /// Gets or sets the flow display mode.
        /// </summary>
        /// <value>The flow display mode.</value>
        public FlowDisplayMode FlowDisplayMode
        {
            get { return _flowDisplayMode; }
            set
            {
                _flowDisplayMode = value;
                OnPropertyChanged("FlowDisplayMode");
            }
        }

        /// <summary>
        /// Gets or sets the flow structure items.
        /// </summary>
        /// <value>The flow structure items.</value>
        public ObservableCollection<FlowTreeModel> FlowStructureItems
        {
            get { return (ObservableCollection<FlowTreeModel>)GetValue(FlowStructureItemsProperty); }
            set { SetValue(FlowStructureItemsProperty, value); }
        }

        /// <summary>
        /// Gets the grid view filter descriptor.
        /// </summary>
        /// <value>The grid view filter descriptor.</value>
        public GridViewFilterDescriptor GridViewFilterDescriptor
        {
            get
            {
                if (customFilterDescriptor == null)
                {
                    customFilterDescriptor = new GridViewFilterDescriptor(GridViewMessages.Columns.OfType<GridViewDataColumn>());
                    GridViewMessages.FilterDescriptors.Add(customFilterDescriptor);
                }
                return customFilterDescriptor;
            }
        }

        /// <summary>
        /// Gets or sets the selected data item tree view.
        /// </summary>
        /// <value>The selected data item tree view.</value>
        public Framework.Pages.Workflow.Models.DataItemTreeView SelectedDataItemTreeView
        {
            get { return (Framework.Pages.Workflow.Models.DataItemTreeView)GetValue(SelectedDataItemTreeViewProperty); }
            set { SetValue(SelectedDataItemTreeViewProperty, value); }
        }

        /// <summary>
        /// Gets or sets the selected data item tree view.
        /// </summary>
        /// <value>The selected data item tree view.</value>
        public Framework.Pages.Workflow.Models.DataItemTreeView SelectedAdminDataItemTreeView { get; set; }

        /// <summary>
        /// Gets or sets the double click timer.
        /// </summary>
        /// <value>The double click timer.</value>
        protected DispatcherTimer DoubleClickTimer { get; set; }

        #endregion Properties

        #region Methods

        private void InitializeWokflowMode()
        {
            WorkflowManager.Activate();

            //Register in messenger to refresh flow list
            Messenger.Default.Register<NotificationMessage>(
                this,
                notification =>
                {
                    if (notification.Notification == "refreshflowlist")
                    {
                        LoadFlow();
                    }
                });

            LoadFlow();

            ActivateAdministrationTab();
        }

        /// <summary>
        /// Gets the data item tree view.
        /// </summary>
        /// <returns></returns>
        public Framework.Pages.Workflow.Models.DataItemTreeView GetDataItemTreeView()
        {
            return tabControl.SelectedIndex == 0 ? SelectedDataItemTreeView : SelectedAdminDataItemTreeView;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FlowPage" /> class.
        /// </summary>
        public void InitDataContext()
        {
            //Data Context Model for classical flow
            DataContextViewModel = new DataViewModel();
            DataContextViewModel.Loaded += new EventHandler(DataContextViewModel_Loaded);
            DataContext = DataContextViewModel;

            //Data Context View for Admin flow 
            AdminDataViewModel = new AdminDataViewModel();
            AdminTabHeader.DataContext = AdminDataViewModel;
        }

        /// <summary>
        /// Changes the display mode.
        /// </summary>
        /// <param name="mode">The mode.</param>
        public void ChangeDisplayMode(FlowDisplayMode mode)
        {
            FlowDisplayMode = mode;

            switch (mode)
            {
                case FlowDisplayMode.Classic:
                    VisualStateManager.GoToState(this, "ClassicState", false);
                    SelectedDataItemTreeView = null;
                    break;
                case FlowDisplayMode.Workflow:
                    VisualStateManager.GoToState(this, "WorkflowState", false);
                    RadTreeViewBox.SelectedItems.Clear();
                    RadTreeViewBox.SelectedItem = null;
                    break;
            }
        }

        /// <summary>
        /// Translation
        /// </summary>
        public void InitLabel()
        {
            buttonRefreshHeader.Text = Resx.GetLabel(ResxFlowPage.REFRESH);
            buttonDisplayHeader.Text = Resx.GetLabel(ResxCommon.DISPLAY);
            buttonDeleteHeader.Text = Resx.GetLabel(ResxCommon.DELETE);
            m_NbMaxTabMessage = Resx.GetLabel(ResxFlowPage.MSG_NB_MAX_TAB);
            m_FolderLbl = Resx.GetLabel(ResxFlowPage.MESSAGE);
            MainTabHeader.Header = Resx.GetLabel(ResxFlowPage.MAINFLOWTAB);
            AdminTabHeader.Header = Resx.GetLabel(ResxFlowPage.ADMINFLOWTAB);
            m_sDeleteMessageHeader = Resx.GetLabel(ResxFlowPage.DELETE);
            m_sDeleteMessage = Resx.GetLabel(ResxFlowPage.DELETE_CONFIRMATION_MESSAGE);
            HeaderTextBlock.Text = Resx.GetLabel(ResxFlowPage.DOCUMENT_TO_VENTILATE);

            GridViewMessages.Columns["ColObjet"].Header = Resx.GetLabel(ResxFlowPage.OBJECT);
            GridViewMessages.Columns["ColExpediteur"].Header = Resx.GetLabel(ResxFlowPage.SENDER);
            GridViewMessages.Columns["ColDestinataires"].Header = Resx.GetLabel(ResxFlowPage.RECEIVER);
            GridViewMessages.Columns["ColDate"].Header = Resx.GetLabel(ResxFlowPage.DATE);

            DeleteContextMenu.Header = Resx.GetLabel(ResxCommon.DELETE);
            DisplayMessageContextMenu.Header = Resx.GetLabel(ResxFlowPage.DISPLAY_MESSAGE_CM);

            AdminPanelBarHeaderTextBlock.Text = Resx.GetLabel(ResxCommon.Flow);
        }

        /// <summary>
        /// Event called when closing a tab of the tab control
        /// </summary>
        /// <param name="sender">tab item</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        public void OnCloseTabClicked(object sender, RoutedEventArgs e)
        {
            var tabItem = sender as RadTabItem;

            if (tabItem != null && ((Grid)tabItem.Content).Children[0] is FolderPage)
            {
                var folderPage = ((FolderPage)((Grid)tabItem.Content).Children[0]);
                if (folderPage != null)
                {
                    folderPage.DataHasChanged -= FolderPageDataHasChanged;
                    folderPage.DocumentCopiedOrCuted -= folderPage_DocumentCopiedOrCuted;
                    folderPage.Dispose();
                }
                m_oTabItemsWorkflow.Remove(tabItem);
                _tabCount--;
            }
            else
            {
                if (tabItem != null)
                {
                    var displayPage = ((DisplayPage)((Grid)tabItem.Content).Children[0]);
                    displayPage.DataHasChanged -= FolderPageDataHasChanged;
                }
            }

            // Remove the item from the collection the control is bound to
            if (tabItem != null)
            {
                tabControl.Items.Remove(tabItem);
                m_oTabItemsFlow.Remove(tabItem);
            }

            //Run the search as new refresh the potentially modified indexes
            if (m_bDataHasChanged)
            {
                RefreshMessages();
            }

            //Set the previous tab index 
            tabControl.SelectedIndex = _lastSelectedTabIndex;
        }

        /// <summary>
        /// Called when [property changed].
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Handles the Checked event of the chkSelectAll control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void chkSelectAll_Checked(object sender, RoutedEventArgs e)
        {
            GridViewMessages.SelectAll();
        }

        /// <summary>
        /// Handles the Unchecked event of the chkSelectAll control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void chkSelectAll_Unchecked(object sender, RoutedEventArgs e)
        {
            if (GridViewMessages.SelectedItems.Count == GridViewMessages.Items.Count)
            {
                GridViewMessages.UnselectAll();
            }
        }

        /// <summary>
        /// Contexts the menu click.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="Telerik.Windows.RadRoutedEventArgs" /> instance containing the event data.</param>
        private void ContextMenuClick(object sender, RadRoutedEventArgs e)
        {
            string l_sContextMenuItem = ((RadMenuItem)e.OriginalSource).Name;
            switch (l_sContextMenuItem)
            {
                case "DeleteContextMenu":
                    DeleteMessages();
                    break;
                case "DisplayMessageContextMenu":
                    DisplayMessages();
                    break;
            }
        }

        /// <summary>
        /// Contexts the menu opened.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void ContextMenuOpened(object sender, RoutedEventArgs e)
        {
            if (GridViewMessages.SelectedItems.Count == 0)
            {
                ContextMenu.IsOpen = false;
            }
            else
            {
                DisplayMessageContextMenu.IsEnabled = GridViewMessages.SelectedItems.Count == 1;
            }
        }

        /// <summary>
        /// Handles the Loaded event of the DataContextViewModel control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs" /> instance containing the event data.</param>
        private void DataContextViewModel_Loaded(object sender, EventArgs e)
        {
            if (RadTreeViewBox.Items != null && RadTreeViewBox.Items.Count > 0 && RadTreeViewBox.SelectedItem == null)
            {
                //Select first item i there is no item selected
                RadTreeViewBox.SelectedItem = RadTreeViewBox.Items[0];
            }

            RadTreeViewBox.Focus();
        }

        /// <summary>
        /// Loads the flow.
        /// </summary>
        private void LoadFlow()
        {
            if (GlobalWebContext.LicenseTerms.LicenseType == LicenseType.Enterprise && !_isLoading)
            {
                _isLoading = true;

                SplashScreenManager.Wait(this);

                if (FlowStructureItems == null)
                {
                    FlowStructureItems = new ObservableCollection<FlowTreeModel>();
                }
                else
                {
                    foreach (var item in FlowStructureItems)
                    {
                        item.Items.Clear();
                    }

                    FlowStructureItems.Clear();
                }

                FlowItemsPanel.Clear();
                WorkflowInstancewMessagesWithIndex.Clear();


                if (SelectedDataItemTreeView != null)
                {
                    WorkflowInstanceList.RefreshWorkflowInstances(SelectedDataItemTreeView);
                }

                /*
                 * Received
                 */

                //Progressing
                BusinessEntitiesDomainContext businessEntitiesDomainContext =
                    GlobalWebContext.BusinessEntitiesDomainContext;
                var getProcessingInstancesCountByReceiverId =
                    businessEntitiesDomainContext.GetProcessingInstancesCountByReceiverIdQuery(
                        GlobalWebContext.CurrentUser.UserId);

                businessEntitiesDomainContext.Load<WkfTuple>(
                    getProcessingInstancesCountByReceiverId,
                    (getProcessingInstancesCountByReceiverIdResult) =>
                    {
                        if (!getProcessingInstancesCountByReceiverIdResult.HasError &&
                            getProcessingInstancesCountByReceiverIdResult.Entities.Count() > 0)
                        {
                            getProcessingInstancesCountByReceiverIdResult.Entities.ToList().ForEach(
                                i =>
                                FlowItemsPanel.AddWkfTuple(i,
                                                           Framework.Pages.Workflow.Models.WorkflowTreeItemType.
                                                               Reception,
                                                           Framework.Pages.Workflow.Models.WorkflowTreeSubItemType.
                                                               Processing));
                        }

                        //Completed
                        businessEntitiesDomainContext = GlobalWebContext.BusinessEntitiesDomainContext;
                        var getCompletedInstancesCountByReceiverId =
                            businessEntitiesDomainContext.GetCompletedInstancesCountByReceiverIdQuery(
                                GlobalWebContext.CurrentUser.UserId);

                        businessEntitiesDomainContext.Load<WkfTuple>(
                            getCompletedInstancesCountByReceiverId,
                            (getCompletedInstancesCountByReceiverIdResult) =>
                            {
                                if (!getCompletedInstancesCountByReceiverIdResult.HasError &&
                                    getCompletedInstancesCountByReceiverIdResult.Entities.Count() > 0)
                                {
                                    getCompletedInstancesCountByReceiverIdResult.Entities.ToList().ForEach(
                                        i =>
                                        FlowItemsPanel.AddWkfTuple(i,
                                                                   Framework.Pages.Workflow.Models.
                                                                       WorkflowTreeItemType.Reception,
                                                                   Framework.Pages.Workflow.Models.
                                                                       WorkflowTreeSubItemType.Completed));
                                }

                                /*
                                 * Send
                                 */

                                //Progressing
                                businessEntitiesDomainContext = GlobalWebContext.BusinessEntitiesDomainContext;
                                var getProcessingInstancesCountBySenderId =
                                    businessEntitiesDomainContext.GetProcessingInstancesCountBySenderIdQuery(
                                        GlobalWebContext.CurrentUser.UserId);

                                businessEntitiesDomainContext.Load<WkfTuple>(
                                    getProcessingInstancesCountBySenderId,
                                    (getProcessingInstancesCountBySenderIdResult) =>
                                    {
                                        if (!getProcessingInstancesCountBySenderIdResult.HasError &&
                                            getProcessingInstancesCountBySenderIdResult.Entities.Count() > 0)
                                        {
                                            getProcessingInstancesCountBySenderIdResult.Entities.ToList().
                                                ForEach(
                                                    i =>
                                                    FlowItemsPanel.AddWkfTuple(i,
                                                                               Framework.Pages.Workflow.
                                                                                   Models.
                                                                                   WorkflowTreeItemType.Send,
                                                                               Framework.Pages.Workflow.
                                                                                   Models.
                                                                                   WorkflowTreeSubItemType.
                                                                                   Processing));
                                        }

                                        //Completed
                                        businessEntitiesDomainContext =
                                            GlobalWebContext.BusinessEntitiesDomainContext;
                                        var getCompletedInstancesCountBySenderId =
                                            businessEntitiesDomainContext.
                                                GetCompletedInstancesCountBySenderIdQuery(
                                                    GlobalWebContext.CurrentUser.UserId);

                                        businessEntitiesDomainContext.Load<WkfTuple>(
                                            getCompletedInstancesCountBySenderId,
                                            (getCompletedInstancesCountBySenderIdResult) =>
                                            {
                                                if (
                                                    !getCompletedInstancesCountBySenderIdResult.HasError &&
                                                    getCompletedInstancesCountBySenderIdResult.Entities.
                                                        Count() > 0)
                                                {
                                                    getCompletedInstancesCountBySenderIdResult.Entities.
                                                        ToList().ForEach(
                                                            i =>
                                                            FlowItemsPanel.AddWkfTuple(i,
                                                                                       Framework.Pages.
                                                                                           Workflow.
                                                                                           Models.
                                                                                           WorkflowTreeItemType
                                                                                           .Send,
                                                                                       Framework.Pages.
                                                                                           Workflow.
                                                                                           Models.
                                                                                           WorkflowTreeSubItemType
                                                                                           .Completed));
                                                }

                                                SplashScreenManager.Stop(this);
                                                _isLoading = false;
                                            },
                                            null);
                                    },
                                    null);
                            },
                            null);
                    },
                    null);
            }
        }

        /// <summary>
        /// Sets the WKF as readed.
        /// </summary>
        /// <param name="instance">The instance.</param>
        /// <param name="dataItemTreeview">The data item treeview.</param>
        private void SetWkfAsReaded(WorkflowInstance instance, Framework.Pages.Workflow.Models.DataItemTreeView dataItemTreeview)
        {
            if (!instance.IsRead)
            {
                BusinessEntitiesDomainContext l_oBEDomainContext = new BusinessEntitiesDomainContext();
                switch (dataItemTreeview.ItemType)
                {
                    case Framework.Pages.Workflow.Models.WorkflowTreeItemType.Reception:
                        l_oBEDomainContext.UpdateUserInstanceToReaded(instance.InstanceUserId, GlobalWebContext.CurrentUser.UserId);
                        break;
                    case Framework.Pages.Workflow.Models.WorkflowTreeItemType.Send:
                        l_oBEDomainContext.UpdateInstanceToReaded(instance.Identifier);
                        break;
                }

                //Update number of new items
                if (dataItemTreeview.NumberNewItem > 0)
                {
                    dataItemTreeview.NumberNewItem--;
                }
            }
        }

        /// <summary>
        /// Handles the DataHasChanged event of the L_oFolderPage control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs" /> instance containing the event data.</param>
        private void FolderPageDataHasChanged(object sender, EventArgs e)
        {
            m_bDataHasChanged = true;
        }

        /// <summary>
        /// This method add a new tab to the tab control each time the user click on a message flow
        /// </summary>
        /// <param name="pageToDisplay">The page to display.</param>
        /// <returns></returns>
        private RadTabItem OpenNewTab(object pageToDisplay)
        {
            RadTabItem itemToAdd = null;
            if (tabControl.Items.Count < 12)
            {
                //Build the tab header
                Grid l_oTabHeaderGrid = new Grid();
                l_oTabHeaderGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
                l_oTabHeaderGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(17, GridUnitType.Pixel) });
                l_oTabHeaderGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });

                //Set the tab label
                TextBlock l_oHeaderText = new TextBlock();
                if (pageToDisplay is DisplayPage)
                {
                    l_oHeaderText.Text = ((DisplayPage)pageToDisplay).m_Message.Objet;
                }
                else if (pageToDisplay is FolderPage)
                {
                    l_oHeaderText.Text = String.Format("{0} {1}", m_FolderLbl, _tabCount++);
                }
                else
                {
                    throw new Exception();
                }

                Grid.SetColumn(l_oHeaderText, 0);
                Grid.SetRow(l_oHeaderText, 0);
                l_oHeaderText.Margin = new Thickness(0, 0, 10, 0);

                Button l_oHeaderCloseButton = new Button();
                Image l_oHeaderImage = new Image { Source = new BitmapImage(new Uri(@"../../Assets/Images/FileClose.png", UriKind.Relative)) };
                l_oHeaderCloseButton.Content = l_oHeaderImage;
                Grid.SetColumn(l_oHeaderCloseButton, 1);
                Grid.SetRow(l_oHeaderCloseButton, 0);

                RoutedEventHelper.SetEnableRoutedClick(l_oHeaderCloseButton, true);

                l_oTabHeaderGrid.Children.Add(l_oHeaderText);
                l_oTabHeaderGrid.Children.Add(l_oHeaderCloseButton);

                //Start building the tab itself adding header and content
                itemToAdd = new RadTabItem { Name = "RadTabItem_" + Guid.NewGuid().ToString(), Header = l_oTabHeaderGrid };

                //Create a grid to load the modification panel
                Grid l_oTabGrid = new Grid();
                l_oTabGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
                l_oTabGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });

                if (pageToDisplay is DisplayPage)
                {
                    //Add the modification panel to the grid
                    l_oTabGrid.Children.Add(pageToDisplay as DisplayPage);
                    (pageToDisplay as DisplayPage).DataHasChanged += FolderPageDataHasChanged;
                }
                else
                {
                    //Add the modification panel to the grid
                    l_oTabGrid.Children.Add(pageToDisplay as FolderPage);
                    (pageToDisplay as FolderPage).DataHasChanged += FolderPageDataHasChanged;
                }

                itemToAdd.Content = l_oTabGrid;
                itemToAdd.IsSelected = true;

                try
                {
                    if (!tabControl.Items.Contains(itemToAdd))
                        tabControl.Items.Add(itemToAdd);
                }
                catch (Exception e)
                {
                    //Random bug
                    MessageBoxChildWindow message = new MessageBoxChildWindow(
                        String.Empty,
                        "Une erreur est survenue lors de l'ouverture du flux. Veuillez ré-essayer.",
                        MessageBoxButtons.Ok,
                        MessageBoxIcon.Error);

                    message.ShowDialog();

                    StringBuilder sb = new StringBuilder("Random error while opening a flow (linked to Telerik RadTabControl) - ");

                    if (pageToDisplay is FolderPage)
                    {
                        FolderPage folderPage = pageToDisplay as FolderPage;
                        sb.AppendFormat(
                            "Organization ID : ({0}) - Folder Type ID : ({1}) - Folder ID : ({2}) - ",
                            folderPage.CurrentOrganization.Identifier,
                            folderPage.CurrentFolderType.Identifier,
                            folderPage.CurrentFolder.Identifier);
                    }

                    sb.AppendFormat("Exception Message : {0} - Exception StackTrace : {1}", e.Message, e.StackTrace);

                    LoggerHelper.Send(
                        GetType().Name,
                        sb.ToString());

                    return null;
                }
            }
            else
            {
                MessageBoxChildWindow message = new MessageBoxChildWindow(String.Empty, m_NbMaxTabMessage, MessageBoxButtons.Ok, MessageBoxIcon.Warning);
                message.ShowDialog();
            }

            return itemToAdd;
        }

        /// <summary>
        /// Displays the workflow folder.
        /// </summary>
        /// <param name="CurrentDataTreeView">The current data tree view.</param>
        /// <param name="organization">The organization.</param>
        /// <param name="folderType">Type of the folder.</param>
        /// <param name="folder">The folder.</param>
        /// <param name="workflowInstance">The workflow instance.</param>
        private void DisplayWorkflowFolder(Framework.Pages.Workflow.Models.DataItemTreeView CurrentDataTreeView, Organization organization, FolderType folderType, Folder folder, WorkflowInstance workflowInstance)
        {

            //Save the current tab index
            _lastSelectedTabIndex = tabControl.SelectedIndex;

            //Create and show new folder Page
            FolderPage folderPage = new FolderPage(organization, folderType, folder, AppDisplayMode.Flow);
            folderPage.DocumentCopiedOrCuted += folderPage_DocumentCopiedOrCuted;
            KeyValuePair<RadTabItem, long> l_oTabItem = m_oTabItemsWorkflow.Where(item => item.Value == workflowInstance.Identifier).FirstOrDefault();
            if (l_oTabItem.Value == 0)
            {
                //Set the instance to readed
                SetWkfAsReaded(workflowInstance, CurrentDataTreeView);

                RadTabItem item = OpenNewTab(folderPage);

                if (item != null)
                    m_oTabItemsWorkflow.Add(item, workflowInstance.Identifier);

            }
            else
            {
                MessageBoxChildWindow l_oMessage = new MessageBoxChildWindow(Resx.GetLabel(ResxFlowPage.FLOW_MSG_USE),
                                                                            Resx.GetLabel(ResxFlowPage.FLOW_MSG_OPEN).Replace("\\n", Environment.NewLine),
                                                                            MessageBoxButtons.Ok,
                                                                            MessageBoxIcon.Warning);
                l_oMessage.ShowDialog();
                l_oMessage.Closed += (s, ev) =>
                {
                    if (l_oMessage.Result == MessageBoxResult.OK)
                    {
                        l_oTabItem.Key.IsSelected = true;
                        SplashScreenManager.Stop(this);
                    }
                };
            }

            bool isSendMode = CurrentDataTreeView.ItemType == Framework.Pages.Workflow.Models.WorkflowTreeItemType.Send;
            folderPage.LoadWorkflow(workflowInstance, isSendMode);

            SplashScreenManager.Stop(this);
        }

        private void folderPage_DocumentCopiedOrCuted(object sender, Framework.Pages.Events.PasteCopyEventArgs args)
        {
            if (tabControl.Items.Count > 2)
            {
                for (int i = 2; i < tabControl.Items.Count; i++)
                {
                    FolderPage folderPage = GetFolderPage((tabControl.Items[i] as RadTabItem));
                    if (folderPage != null && folderPage.CommentChildWindow != null)
                    {
                        if (folderPage.CurrentFolder != args.SourceFolder)
                        {
                            folderPage.ReloadPasteMenuVisibility();

                            if (args.Action == PasteCopyActionType.Paste)
                            {
                                //refresh folder and flow
                                folderPage.LoadDocumentsFolder();
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Handles the SelectionChanged event of the tabControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void TabControlSelectionChanged(object sender, RoutedEventArgs e)
        {
            //Disable all open notes when we return on the search tab
            if (tabControl.Items.Count > 2)
                for (int i = 2; i < tabControl.Items.Count; i++)
                {
                    FolderPage folderPage = GetFolderPage((tabControl.Items[i] as RadTabItem));
                    if (folderPage != null && folderPage.CommentChildWindow != null)
                        folderPage.CommentChildWindow.Visibility = Visibility.Collapsed;
                }

            if (tabControl.SelectedIndex < 2)
            {
                if (m_bDataHasChanged)
                {
                    if (FlowDisplayMode == FlowDisplayMode.Classic)
                        RefreshMessages();
                    else
                        WorkflowInstanceList.RefreshWorkflowInstances(SelectedDataItemTreeView);

                    m_bDataHasChanged = false;
                }
            }
            else
            {
                //Re-open the note when we return on the FolderPage
                FolderPage folderPage = GetFolderPage(tabControl.SelectedItem as RadTabItem);

                if (folderPage != null && folderPage.CommentChildWindow != null)
                {
                    if (folderPage.CommentChildWindow != null && (folderPage.CommentChildWindow.MustBeOpen))
                        folderPage.CommentChildWindow.Visibility = Visibility.Visible;
                }

            }
        }

        private FolderPage GetFolderPage(RadTabItem item)
        {
            FolderPage folderPage = (((Panel)(item.Content)).Children[0]) as FolderPage;

            return folderPage;
        }

        /// <summary>
        /// Activates the administration tab.
        /// </summary>
        private void ActivateAdministrationTab()
        {
            bool result = false;

            if (GlobalWebContext.LicenseTerms.LicenseType == LicenseType.Enterprise)
            {
                foreach (var group in GlobalWebContext.CurrentUser.GroupList)
                {
                    if (group.IsAdministrator)
                    {
                        result = true;
                        break;
                    }
                }
            }

            AdminTabHeader.Visibility = (result ? Visibility.Visible : Visibility.Collapsed);
        }

        #endregion Methods

        #region Classical flow

        /// <summary>
        /// Handles the Click event of the buttonDelete control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void buttonDelete_Click(object sender, RoutedEventArgs e)
        {
            DeleteMessages();
        }

        /// <summary>
        /// Handles the Click event of the buttonDisplay control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void buttonDisplay_Click(object sender, RoutedEventArgs e)
        {
            DisplayMessages();
        }

        /// <summary>
        /// Handles the Click event of the buttonRefresh control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs" /> instance containing the event data.</param>
        private void buttonRefresh_Click(object sender, RoutedEventArgs e)
        {
            RefreshMessages();
        }

        /// <summary>
        /// This event is called when a user has selected and deleted some message.
        /// </summary>
        /// <param name="result"></param>
        private void OnDeleteMessageFlowQueryCallback(LoadOperation<ReturnObject> result)
        {
            try
            {
                List<ReturnObject> l_oReturnObjects = new List<ReturnObject>(result.Entities);
                if (l_oReturnObjects.First().IsValid)
                {
                    foreach (MessageFlowDisp item in m_oSelectedListMsg)
                    {
                        Framework.Pages.Workflow.Models.DataItemTreeView dataItemTreeView = null;

                        //Check if it's the "receive" or "Send" item
                        if (item.GroupId != 0)
                        {
                            dataItemTreeView = DataContextViewModel.ItemsTreeView[0];
                        }
                        else if (item.GroupId == 0)
                        {
                            dataItemTreeView = DataContextViewModel.ItemsTreeView[1];
                        }

                        //Check if it's an "Unread" message that have been deleted
                        if (item.MyDocEtat == 0)
                        {
                            if (dataItemTreeView != null)
                                dataItemTreeView.NumberNewItem = dataItemTreeView.NumberNewItem != 0 ? dataItemTreeView.NumberNewItem - 1 : dataItemTreeView.NumberNewItem;
                        }

                        //Delete on all messages
                        if (dataItemTreeView != null)
                            dataItemTreeView.NumberItem = dataItemTreeView.NumberItem != 0 ? dataItemTreeView.NumberItem - 1 : dataItemTreeView.NumberItem;

                        ((Framework.Pages.Workflow.Models.DataItemTreeView)RadTreeViewBox.SelectedItem).CollectionMessage.Remove(item);
                    }
                }
                else
                {
                    throw new Exception("No List of Document Entity retrieved");
                }
                GridViewMessages.UnselectAll();
            }
            catch (Exception ex)
            {
                //Logger.Write("EXCEPTION : " + Environment.NewLine + ex, Logger.Level.Error);
                MessageBoxChildWindow L_oMessage = new MessageBoxChildWindow(String.Empty, " -> OnDeleteMessageFlowQueryCallback failure Error : " + Environment.NewLine + ex.Message, MessageBoxButtons.Ok, MessageBoxIcon.Error);
                L_oMessage.ShowDialog();
            }
        }

        /// <summary>
        /// This callback is called each time a user wants to open a message, in order to update the message status
        /// </summary>
        /// <param name="p_oMessageFlow"></param>
        public void UpdateStateDocListQueryCallback(MessageFlowDisp p_oMessageFlow)
        {
            if (p_oMessageFlow.GroupId != 0 && p_oMessageFlow.MyDocEtat == 0)
            {
                Framework.Pages.Workflow.Models.DataItemTreeView receipt = DataContextViewModel.ItemsTreeView[0];
                receipt.NumberNewItem = receipt.NumberNewItem - 1;
                p_oMessageFlow.MyDocEtat = 1;
            }

            DisplayPage page = new DisplayPage(p_oMessageFlow);

            //We use the value as both key and value are unique
            KeyValuePair<RadTabItem, long> l_oTabItem = m_oTabItemsFlow.Where(item => item.Value == p_oMessageFlow.Identifier).FirstOrDefault();

            if (l_oTabItem.Value == 0)
            {
                RadTabItem l_oAddedItem = OpenNewTab(page);
                if (l_oAddedItem != null)
                {
                    m_oTabItemsFlow.Add(l_oAddedItem, p_oMessageFlow.Identifier);
                }
            }
            else
            {
                MessageBoxChildWindow l_oMessage = new MessageBoxChildWindow(Resx.GetLabel(ResxFlowPage.FLOW_MSG_USE),
                                                                            Resx.GetLabel(ResxFlowPage.FLOW_MSG_OPEN).Replace("\\n", Environment.NewLine),
                                                                            MessageBoxButtons.Ok,
                                                                            MessageBoxIcon.Warning);

                l_oMessage.ShowDialog();
                l_oMessage.Closed += (s, ev) =>
                {
                    if (l_oMessage.Result == MessageBoxResult.OK)
                    {
                        l_oTabItem.Key.IsSelected = true;
                        SplashScreenManager.Stop(this);
                    }
                };

            }
        }

        /// <summary>
        /// This method load latest messages from the database
        /// </summary>
        private void RefreshMessages()
        {
            if (FlowDisplayMode == FlowDisplayMode.Classic)
            {
                Framework.Pages.Workflow.Models.DataItemTreeView selectedItem = (RadTreeViewBox.SelectedItem as Framework.Pages.Workflow.Models.DataItemTreeView);

                DataContextViewModel.MessagesLoaded(selectedItem);

                GridViewMessages.UnselectAll();
            }
        }

        /// <summary>
        /// This methode is in charge to delete messages in the gridview
        /// </summary>
        private void DeleteMessages()
        {
            MessageBoxChildWindow l_MsgDelete = new MessageBoxChildWindow(m_sDeleteMessageHeader, m_sDeleteMessage, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            l_MsgDelete.ShowDialog();

            l_MsgDelete.Closed += (s, ev) =>
            {
                if (l_MsgDelete.Result == MessageBoxResult.Yes)
                {
                    if (FlowDisplayMode == FlowDisplayMode.Classic)
                    {
                        List<long> l_oMessageFlowIds = new List<long>();
                        List<long> l_oGroupIds = new List<long>();
                        bool l_bIsUser = false;
                        m_oSelectedListMsg = new List<MessageFlowDisp>();
                        foreach (MessageFlowDisp item in GridViewMessages.SelectedItems)
                        {
                            m_oSelectedListMsg.Add(item);

                            l_bIsUser = item.GroupId == 0;
                            if (l_bIsUser)
                            {
                                l_oMessageFlowIds.Add(item.Identifier);
                            }
                            else
                            {
                                l_oMessageFlowIds.Add(item.Identifier);
                                l_oGroupIds.Add(item.RguId);
                            }
                        }
                        BusinessEntitiesDomainContext l_oBEDomainContext = new BusinessEntitiesDomainContext();

                        if (l_bIsUser)
                        {
                            var query = l_oBEDomainContext.DeleteMessageFlowQuery(l_oMessageFlowIds);
                            l_oBEDomainContext.Load(query, OnDeleteMessageFlowQueryCallback, null);
                        }
                        else
                        {
                            var query = l_oBEDomainContext.DeleteMessageFlowUserQuery(l_oMessageFlowIds, l_oGroupIds);
                            l_oBEDomainContext.Load(query, OnDeleteMessageFlowQueryCallback, null);
                        }
                    }
                }
            };
        }

        /// <summary>
        /// This method evaluates the action to do when a user wants to aopen a message 
        /// </summary>
        private void DisplayMessages()
        {
            if (FlowDisplayMode == FlowDisplayMode.Classic)
            {
                foreach (MessageFlowDisp item in GridViewMessages.SelectedItems)
                {
                    if (item.GroupId != 0)
                    {
                        UpdateStateDocListQueryCallback(item);
                    }
                    else
                    {
                        UpdateMessageFlowLastReadDateQuery(item);
                    }
                }
            }
        }

        /// <summary>
        /// Use for double click implementation
        /// too much time has passed for it to be a double click.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DoubleClick_Timer(object sender, EventArgs e)
        {
            DoubleClickTimer.Stop();
        }

        /// <summary>
        /// Event raised by the click on a cell
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Item_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (DoubleClickTimer.IsEnabled)
            {
                // a double click has occured
                DoubleClickTimer.Stop();

                if (sender.GetType().Equals(typeof(RadGridView)) && ((RadGridView)sender).SelectedItems.Count == 1)
                {
                    GridViewCell l_oCell = ((RadGridView)sender).CurrentCell;
                    if (l_oCell != null && l_oCell.ParentRow != null)
                    {
                        l_oCell.ParentRow.FontWeight = FontWeights.Normal;
                        DisplayMessages();
                    }
                }
            }
            else
            {
                DoubleClickTimer.Start();
            }
        }

        /// <summary>
        /// Handles the Deleting event of the GridViewMessages control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.Controls.GridViewDeletingEventArgs" /> instance containing the event data.</param>
        private void GridViewMessages_Deleting(object sender, GridViewDeletingEventArgs e)
        {
            e.Cancel = true;
            DeleteMessages();
        }

        /// <summary>
        /// Handles the SelectionChanged event of the GridViewMessages control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.Controls.SelectionChangeEventArgs" /> instance containing the event data.</param>
        private void GridViewMessages_SelectionChanged(object sender, SelectionChangeEventArgs e)
        {
            RadGridView gridViewSource = sender as RadGridView;

            if (gridViewSource != null && gridViewSource.SelectedItems.Count == 0)
            {
                buttonDelete.IsEnabled = false;
                buttonDisplay.IsEnabled = false;
            }
            else
            {
                buttonDelete.IsEnabled = true;

                if (gridViewSource != null && gridViewSource.SelectedItems.Count != 1)
                {
                    buttonDisplay.IsEnabled = false;
                }
                else
                {
                    buttonDisplay.IsEnabled = true;
                }
            }
        }

        /// <summary>
        /// This event is called when the sender click on a message flow in his "SENT BOX".
        /// </summary>
        /// <param name="p_oMessageFlow"></param>
        private void UpdateMessageFlowLastReadDateQuery(MessageFlowDisp p_oMessageFlow)
        {
            Framework.Pages.Workflow.Models.DataItemTreeView l_oSentBox = DataContextViewModel.ItemsTreeView[1];
            if (p_oMessageFlow.MyDocEtat == 0)
            {
                l_oSentBox.NumberNewItem = l_oSentBox.NumberNewItem - 1;
                p_oMessageFlow.LastReadDate = DateTime.Now;
                p_oMessageFlow.MyDocEtat = 1;
            }
            DisplayPage page = new DisplayPage(p_oMessageFlow);

            //We use the value as both key and value are unique
            KeyValuePair<RadTabItem, long> l_oTabItem = m_oTabItemsFlow.Where(item => item.Value == p_oMessageFlow.Identifier).FirstOrDefault();

            if (l_oTabItem.Value == 0)
            {

                RadTabItem l_oAddedItem = OpenNewTab(page);
                if (l_oAddedItem != null)
                {
                    m_oTabItemsFlow.Add(l_oAddedItem, p_oMessageFlow.Identifier);
                }
            }
            else
            {
                MessageBoxChildWindow l_oMessage = new MessageBoxChildWindow(Resx.GetLabel(ResxFlowPage.FLOW_MSG_USE),
                                                                                            Resx.GetLabel(ResxFlowPage.FLOW_MSG_OPEN).Replace("\\n", Environment.NewLine),
                                                                                            MessageBoxButtons.Ok,
                                                                                            MessageBoxIcon.Warning);
                l_oMessage.ShowDialog();
                l_oMessage.Closed += (s, ev) =>
                {
                    if (l_oMessage.Result == MessageBoxResult.OK)
                    {
                        l_oTabItem.Key.IsSelected = true;
                        SplashScreenManager.Stop(this);
                    }
                };
            }
        }

        #endregion

        #region Workflow Actions

        /// <summary>
        /// Handles the SelectionChanged event of the RadTreeViewBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.Controls.SelectionChangedEventArgs" /> instance containing the event data.</param>
        private void RadTreeViewBox_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e)
        {
            Framework.Pages.Workflow.Models.DataItemTreeView L_Item = RadTreeViewBox.SelectedItem as Framework.Pages.Workflow.Models.DataItemTreeView;

            if ((L_Item != null) && (DataContextViewModel != null))
            {
                DataContextViewModel.SelectedItemListMessage = L_Item.CollectionMessage;

                GridViewMessages.UnselectAll();

                ChangeDisplayMode(FlowDisplayMode.Classic);
            }

            buttonDelete.IsEnabled = false;
            buttonDisplay.IsEnabled = false;
        }

        /// <summary>
        /// Handles the WorkflowInstanceListDeleted event of the WorkflowInstanceList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs" /> instance containing the event data.</param>
        private void WorkflowInstanceList_WorkflowInstanceListDeleted(object sender, EventArgs e)
        {
            LoadFlow();
        }

        /// <summary>
        /// Handles the WorkflowInstanceListRefreshed event of the WorkflowInstanceList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs" /> instance containing the event data.</param>
        private void WorkflowInstanceList_WorkflowInstanceListRefreshed(object sender, EventArgs e)
        {
            //LoadFlow();
        }

        #endregion

        #region Workflow Administration

        /// <summary>
        /// Handles the SelectionChanged event of the RadTreeViewAdminBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Telerik.Windows.Controls.SelectionChangedEventArgs" /> instance containing the event data.</param>
        private void RadTreeViewAdminBox_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e)
        {
            Framework.Pages.Workflow.Models.DataItemTreeView L_Item = RadTreeViewAdminBox.SelectedItem as Framework.Pages.Workflow.Models.DataItemTreeView;
            if ((L_Item != null) && (AdminDataViewModel != null))
            {
                SelectedAdminDataItemTreeView = L_Item;
                SelectedAdminDataItemTreeView.OrganizationId = OrganizationTypeControl.SelectedOrganization.Identifier;
                SelectedAdminDataItemTreeView.FolderTypeId = OrganizationTypeControl.SelectedFolderType.Identifier;

                WorkflowAdminInstanceList.Organization = OrganizationTypeControl.SelectedOrganization;
                WorkflowAdminInstanceList.FolderType = OrganizationTypeControl.SelectedFolderType;

                WorkflowAdminInstanceList.RefreshWorkflowInstances(SelectedAdminDataItemTreeView);
            }
        }

        /// <summary>
        /// Workflows the admin instance list workflow instance displaying.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void OnWorkflowInstanceDisplaying(object sender, DisplayWorkflowInstanceListEventArgs args)
        {
            SplashScreenManager.Wait(this);

            Organization organization = GlobalWebContext.CurrentUser.GroupList.SelectMany(g => g.OrganizationList).Where(o => o.Identifier == args.CurrentDataItemTreeView.OrganizationId).FirstOrDefault();
            FolderType folderType = GlobalWebContext.CurrentUser.GroupList.SelectMany(g => g.OrganizationList).SelectMany(o => o.FolderTypesList).Where(ft => ft.Identifier == args.CurrentDataItemTreeView.FolderTypeId).FirstOrDefault();

            DisplayWorkflowFolder(GetDataItemTreeView(), organization, folderType, args.Folder, args.WorkflowInstance);
        }

        /// <summary>
        /// Handles the WorkflowInstanceListDeleted event of the WorkflowAdminInstanceList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs" /> instance containing the event data.</param>
        private void WorkflowAdminInstanceList_WorkflowInstanceListDeleted(object sender, EventArgs e)
        {
            WorkflowAdminInstanceList.RefreshWorkflowInstances(SelectedAdminDataItemTreeView);
        }

        /// <summary>
        /// Handles the WorkflowInstanceListRefreshed event of the WorkflowAdminInstanceList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs" /> instance containing the event data.</param>
        private void WorkflowAdminInstanceList_WorkflowInstanceListRefreshed(object sender, EventArgs e)
        {
            WorkflowAdminInstanceList.RefreshWorkflowInstances(SelectedAdminDataItemTreeView);
        }

        /// <summary>
        /// Handles the OrganizationSelected event of the OrganizationTypeControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="args">The <see cref="Rio.Framework.Pages.Controls.OrganizationSelectedEventArgs" /> instance containing the event data.</param>
        private void OrganizationTypeControl_OrganizationSelected(object sender, OrganizationSelectedEventArgs args)
        {
            RadTreeViewAdminBox.IsEnabled = false;
        }

        /// <summary>
        /// Handles the FolderSelected event of the OrganizationTypeControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="args">The <see cref="Rio.Framework.Pages.Controls.FolderSelectedEventArgs" /> instance containing the event data.</param>
        private void OrganizationTypeControl_FolderSelected(object sender, FolderSelectedEventArgs args)
        {
            RadTreeViewAdminBox.IsEnabled = args.FolderType != null;
            WorkflowAdminInstanceList.RefreshWorkflowInstances(SelectedAdminDataItemTreeView);
        }

        #endregion

    }

    /// <summary>
    /// Routed event handler class used to route a buttun click event to another
    /// </summary>
    public class RoutedEventHelper
    {
        #region Fields

        //Create the routed event:
        public static readonly Telerik.Windows.RoutedEvent CloseTabEvent = EventManager.RegisterRoutedEvent(
            "CloseTab",
            RoutingStrategy.Bubble,
            typeof(RoutedEventHandler),
            typeof(RoutedEventHelper));

        // Using a DependencyProperty as the backing store for EnableRoutedClick.
        // This enables animation, styling, binding, etc...
        public static readonly DependencyProperty EnableRoutedClickProperty = DependencyProperty.RegisterAttached(
            "EnableRoutedClick",
            typeof(bool),
            typeof(RoutedEventHelper),
            new System.Windows.PropertyMetadata(OnEnableRoutedClickChanged));

        #endregion Fields

        #region Methods

        //Add an attached property:
        public static bool GetEnableRoutedClick(DependencyObject obj)
        {
            return (bool)obj.GetValue(EnableRoutedClickProperty);
        }

        public static void SetEnableRoutedClick(DependencyObject obj, bool value)
        {
            obj.SetValue(EnableRoutedClickProperty, value);
        }

        static void OnButtonClick(object sender, RoutedEventArgs e)
        {
            var control = sender as Control;
            if (control != null)
            {
                control.RaiseEvent(new RadRoutedEventArgs(RoutedEventHelper.CloseTabEvent, control));
            }
        }

        private static void OnEnableRoutedClickChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var newValue = (bool)e.NewValue;
            var button = sender as Button;
            if (button == null)
                return;
            if (newValue)
                button.Click += new RoutedEventHandler(OnButtonClick);
        }

        #endregion Methods
    }
}
